<template>
  <div>
    <draggable
      v-if="isDrag"
      class="list-wrap"
      v-model="uploadList"
      v-bind="dragOptions"
      @start="drag = true"
      @end="dragEnd"
    >
      <transition-group tag="ul">
        <li
          class="demo-upload-list"
          v-for="(item, index) in uploadList"
          :key="item.uid"
          :style="
            'width:' +
            width +
            'px;height:' +
            height +
            'px;line-height: ' +
            height +
            'px;margin-right:' +
            mr +
            'px;'
          "
        >
          <template v-if="item.status === 'finished'">
            <div v-if="fileType === '视频'" class="qw-videolist-box">
              <video-player
                class="vjs-custom-skin"
                ref="videoPlayer"
                :playsinline="true"
                :options="item.playerOptions"
              ></video-player>
              <div class="demo-upload-list-cover" v-if="!readOnly">
                <Icon
                  type="ios-trash-outline"
                  @click.native="handleRemove(item)"
                ></Icon>
              </div>
            </div>
            <template v-else>
              <img :src="item.url" />
              <div class="demo-upload-list-cover">
                <Icon
                  type="ios-eye-outline"
                  @click.native="handleView(item.url)"
                  style="margin-right: 20px"
                ></Icon>
                <Icon
                  type="ios-trash-outline"
                  v-if="!readOnly"
                  @click.native="handleRemove(item)"
                >
                </Icon>
              </div>
            </template>
          </template>
          <template v-else>
            <Progress
              v-if="item.showProgress"
              :percent="item.percentage"
              hide-info
            ></Progress>
          </template>
          <div class="qw-imglist-corner" v-if="corner[index]">
            {{ corner[index] }}
          </div>
          <div class="qw-imglist-corner">
            <slot name="corner"></slot>
          </div>
        </li>
      </transition-group>
    </draggable>
    <!-- <template>
      <div
        class="demo-upload-list"
        v-for="(item, index) in uploadList"
        :key="index"
        :style="
          'width:' +
          width +
          'px;height:' +
          height +
          'px;line-height: ' +
          height +
          'px;margin-right:' +
          mr +
          'px;'
        "
      >
        <template v-if="item.status === 'finished'">
          <div v-if="fileType === '视频'" class="qw-videolist-box">
            <video-player
              class="vjs-custom-skin"
              ref="videoPlayer"
              :playsinline="true"
              :options="item.playerOptions"
            ></video-player>
            <div class="demo-upload-list-cover" v-if="!readOnly">
              <Icon
                type="ios-trash-outline"
                @click.native="handleRemove(item)"
              ></Icon>
            </div>
          </div>
          <template v-else>
            <img :src="item.url" />
            <div class="demo-upload-list-cover">
              <Icon
                type="ios-eye-outline"
                @click.native="handleView(item.url)"
              ></Icon>
              <Icon
                type="ios-trash-outline"
                v-if="!readOnly"
                @click.native="handleRemove(item)"
              ></Icon>
            </div>
          </template>
        </template>
        <template v-else>
          <Progress
            v-if="item.showProgress"
            :percent="item.percentage"
            hide-info
          ></Progress>
        </template>

        <div class="qw-imglist-corner" v-if="corner[index]">
          {{ corner[index] }}
        </div>
        <div class="qw-imglist-corner">
          <slot name="corner"></slot>
        </div>
      </div>
    </template> -->
    <Upload
      class="upload"
      :multiple="isMultiple"
      v-show="uploadList.length < maxLen && !readOnly"
      ref="upload"
      name="myfile"
      :show-upload-list="false"
      :default-file-list="showImgList"
      :on-success="handleSuccess"
      :format="format"
      :max-size="maxSize"
      :on-progress="handleUpload"
      :on-format-error="handleFormatError"
      :on-exceeded-size="handleMaxSize"
      :before-upload="handleBeforeUpload"
      type="drag"
      :action="uploadBaseURL + methodUpload"
      :style="
        'display: inline-block;width:' + width + 'px;margin-right:' + mr + 'px;'
      "
    >
      <div
        class="qw-camera"
        :style="
          'width: ' +
          width +
          'px;height:' +
          height +
          'px;line-height: ' +
          height +
          'px;margin-right:' +
          mr +
          'px;'
        "
      >
        <Icon type="ios-camera" size="20"></Icon>
        <div class="qw-imglist-corner">
          <slot name="corner"></slot>
        </div>
        <Spin fix style="line-height: 24px" v-if="isUping">
          <Icon type="ios-loading" size="18" class="demo-spin-icon-load"></Icon>
          <div>上传中</div>
        </Spin>
      </div>
    </Upload>
    <p v-show="showTip && isMultiple && !readOnly" class="warn_color">提示：可以添加{{ maxLen }}张</p>
    <Modal title="大图展示" v-model="visible" :width="previewModalWidth">
      <img :src="imgUrl" v-if="visible" style="width: 100%" />
    </Modal>
  </div>
</template>
<script>
import draggable from 'vuedraggable';
export default {
  components: {
    draggable
  },
  props: {
    isMultiple: {
      type: Boolean,
      default: false
    },
    // 组件定义名称
    name: {
      type: String
    },
    // 文件类型
    fileType: {
      type: String,
      default: '图片'
    },
    // 文件格式
    format: {
      type: Array
    },
    // 文字角标
    corner: {
      type: Array,
      default () {
        return [];
      }
    },
    // 图片大小限制
    maxSize: {
      type: Number
    },
    // 右边距
    mr: {
      type: Number,
      default: 4
    },
    // 图片数量显示
    maxLen: {
      type: Number
    },
    // 宽
    width: {
      type: Number,
      default: 120
    },
    // 高
    height: {
      type: Number,
      default: 120
    },
    // 默认回显列表
    defaultList: {
      type: Array
    },
    // 是否只读
    readOnly: {
      type: Boolean,
      default: false
    },
    // 是否可拖拽排序
    isDrag: {
      type: Boolean,
      default: true
    },
    finish: {
      // 视频是否上传结束
      type: String
    },
    uploadForQualification: {
      type: String,
      default: ''
    },
    uploadForQualificationURL: {
      type: String,
      default: ''
    },
    previewModalWidth: {
      type: String,
      default: '60%'
    },
    showTip: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      showImgList: [],
      uploadList: [], // 上传文件列表
      /* defaultList:[], */
      imgUrl: '',
      visible: false,
      isUping: false,
      drag: false
    };
  },
  computed: {
    dragOptions () {
      return {
        animation: 200,
        group: 'description',
        disabled: false,
        ghostClass: 'ghost'
      };
    },
    methodUpload () {
      return this.uploadForQualification === ''
        ? this.uploadMethord
        : this.uploadForQualification;
    },
    showPicUrl () {
      return this.uploadForQualificationURL === ''
        ? this.IMAGEURL
        : this.uploadForQualificationURL;
    }
  },
  watch: {
    defaultList (n, o) {
      console.log(n);
      this.defaultShow(n);
    }
  },
  mounted () {
    this.defaultShow(this.defaultList);
  },
  methods: {
    handleUpload (event, file, fileList) {
      if (this.fileType === '视频') {
        this.$emit('finish', 'false');
      }
    },
    // 默认显示数据
    defaultShow (defaultList) {
      let prefixUrl =
        this.fileType === '视频' ? this.videoBaseURL : this.showPicUrl;
      // fmd - 2021-9-1 过滤有路径的图片塞，防止出现没有路径也给src路径导致图片丢失的情况出现
      let dFault = _.filter(defaultList, item => {
        return item.url;
      });
      // let dFault = defaultList;
      if (this.fileType === '视频') {
        dFault.forEach(item => {
          let sources = [];
          sources.push({
            type: '', // 这里的种类支持很多种：基本视频格式、直播、流媒体等，具体可以参看git网址项目
            src: item.url // url地址
          });
          item.playerOptions = {
            // playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度
            autoplay: false, // 如果true,浏览器准备好时开始回放。
            muted: false, // 默认情况下将会消除任何音频。
            loop: false, // 导致视频一结束就重新开始。
            preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频（如果浏览器支持）
            language: 'zh-CN',
            aspectRatio: '4:3', // 将播放器置于流畅模式，并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字（例如"16:9"或"4:3"）
            fluid: true, // 当true时，Video.js player将拥有流体大小。换句话说，它将按比例缩放以适应其容器。
            sources: sources,
            poster: item.poster ? item.poster : '', // 你的封面地址
            // width: document.documentElement.clientWidth, //播放器宽度
            notSupportedMessage: '此视频暂无法播放，请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
            controlBar: {
              timeDivider: false,
              durationDisplay: false,
              remainingTimeDisplay: false,
              fullscreenToggle: true // 全屏按钮
            }
          };
        });
      }
      this.showImgList = dFault.map(item => {
        let obj = { ...item };
        let reg = /^(http|https):\/\//;
        // 判断是否已经拼接了基础路径
        if (!reg.test(obj.url)) {
          let src = obj.url;
          obj.url = `${prefixUrl}${src}?${this.XOSSPROCE}`;
        }
        return obj;
      });
      this.$nextTick(() => {
        this.uploadList = this.$refs.upload.fileList;
      });
    },
    // 截取字符串
    handleSplitArr (arr) {
      let prefixUrl = this.IMAGEURL;
      let XOSSPROCE = '\\?' + this.XOSSPROCE;
      let list = arr.map(item => {
        let obj = { ...item };
        let pattern = `(${prefixUrl}|${XOSSPROCE})`;
        let reg = new RegExp(pattern);
        // 判断是否已经拼接了基础路径
        let src = obj.url;
        if (reg.test(obj.url)) {
          let regs = new RegExp(pattern, 'g');
          src = src.replace(regs, '');
        }
        obj.url = src;
        return obj;
      });
      return list;
    },
    dragEnd () {
      this.drag = false;
      let data = this.handleSplitArr(this.uploadList);
      this.$emit('handleChangeImage', data);
    },
    handleChange (file) {
      this.isUping = false;
      this.uploadList = this.$refs.upload.fileList;
      /* 获取当前上传action且状态为非finished的对象index */
      if (file) {
        const uploadIndex = this.uploadList.findIndex(item => {
          return (file.uid === item.uid && item.status !== 'finished');
        })
        if (uploadIndex !== -1) {
          this.uploadList[uploadIndex] = file;
        }
      }
      /* 如果列表全部文件状态都为finished才通过，向父组件emit数据 */
      const overUploadFlag = this.uploadList.every(item => { return item.status === 'finished' })
      if (!overUploadFlag) { return false }
      let data = this.handleSplitArr(this.uploadList);
      this.$emit('handleChangeImage', data);
    },
    // 预览图片
    handleView (url) {
      this.imgUrl = url;
      this.visible = true;
    },
    // 移除图片
    handleRemove (file) {
      const fileList = this.$refs.upload.fileList;
      this.$refs.upload.fileList.splice(fileList.indexOf(file), 1);

      this.handleChange();
    },
    // 上传成功
    handleSuccess (res, file, fileList) {
      // let prefixUrl = this.fileType === '视频' ? this.videoBaseURL : this.imgBaseURL;
      file.url = res.retData;
      let sources = [];
      sources.push({
        type: '', // 这里的种类支持很多种：基本视频格式、直播、流媒体等，具体可以参看git网址项目
        src: res.retData // url地址
      });
      file.playerOptions = {
        // playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度
        autoplay: false, // 如果true,浏览器准备好时开始回放。
        muted: false, // 默认情况下将会消除任何音频。
        loop: false, // 导致视频一结束就重新开始。
        preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频（如果浏览器支持）
        language: 'zh-CN',
        aspectRatio: '16:9', // 将播放器置于流畅模式，并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字（例如"16:9"或"4:3"）
        fluid: true, // 当true时，Video.js player将拥有流体大小。换句话说，它将按比例缩放以适应其容器。
        sources: sources,
        poster: '', // 你的封面地址
        // width: document.documentElement.clientWidth, //播放器宽度
        notSupportedMessage: '此视频暂无法播放，请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
        controlBar: {
          timeDivider: false,
          durationDisplay: false,
          remainingTimeDisplay: false,
          fullscreenToggle: true // 全屏按钮
        }
      };

      if (this.fileType === '视频') {
        this.$emit('finish', true);
      }
      this.handleChange(file);
    },
    // 上传出错
    handleFormatError (file) {
      let fileType = this.format.join(',');
      this.$Notice.warning({
        title: this.fileType + '格式不正确',
        desc:
          this.fileType +
          file.name +
          '格式不正确, 请选择' +
          fileType +
          '格式的.' +
          this.fileType
      });
      this.isUping = false;
    },
    // 上传最大限制
    handleMaxSize (file) {
      let sizeStr = '';
      if (this.maxSize > 1000) {
        if (this.maxSize === 26624) {
          sizeStr = '25M';
        } else {
          sizeStr = parseInt(this.maxSize / 1000) + 'M';
        }
      } else {
        sizeStr = this.maxSize = 'Kb';
      }
      this.$Notice.warning({
        title: '超出文件大小限制',
        desc:
          this.fileType +
          file.name +
          ' 太大了, 请确保' +
          this.fileType +
          '在' +
          sizeStr +
          '以内.'
      });
      this.isUping = false;
    },
    // 上传前校验
    handleBeforeUpload () {
      this.isUping = true;
      const check = this.uploadList.length < this.maxLen;
      if (!check) {
        this.$Notice.warning({
          title: '上传' + this.fileType + '达到最大限制.'
        });
        this.isUping = false;
      }
      return check;
    }
  }
};
</script>
<style lang="less" scoped>
.list-wrap {
  float: left;
}
.qw-disflex {
  display: inline-block;
}

.demo-upload-list {
  display: inline-block;
  width: 60px;
  height: 60px;
  text-align: center;
  line-height: 60px;
  border: 1px solid transparent;
  border-radius: 4px;
  overflow: hidden;
  background: #fff;
  position: relative;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
  margin-right: 4px;
}

.demo-upload-list img {
  width: 100%;
  height: 100%;
}

.demo-upload-list-cover {
  display: none;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.6);
}

.demo-upload-list:hover .demo-upload-list-cover {
  display: block;
}

.demo-upload-list-cover i {
  color: #fff;
  font-size: 20px;
  cursor: pointer;
  margin: 0 2px;
}

.demo-upload-camera {
  width: 58px;
  height: 58px;
  line-height: 58px;
}

.qw-camera {
  position: relative;
  overflow: hidden;
}

.qw-imglist-corner {
  position: absolute;
  right: -33px;
  top: 8px;
  background: #2d8cf0;
  color: #fff;
  font-size: 12px;
  line-height: 26px;
  padding: 0 30px;
  transform: rotate(45deg);
}

.qw-videolist-box {
  width: 100%;
  height: 100%;

  .demo-upload-list-cover {
    height: 30px;
    line-height: 30px;
    background: #2d8cf0;
    z-index: 1;
    bottom: auto;
    right: auto;
    border-bottom-right-radius: 10px;
  }

  & /deep/ .video-player {
    width: 100%;
    height: 100%;
    border-radius: 4px;
    overflow: hidden;

    & .video-js {
      height: 100%;

      .vjs-icon-placeholder {
        width: 100%;
        height: 100%;
        display: block;
      }

      .vjs-volume-panel,
      .vjs-current-time,
      .vjs-progress-control {
        display: none;
      }
    }

    & .vjs-fullscreen {
      .vjs-volume-panel,
      .vjs-current-time,
      .vjs-progress-control {
        display: flex;
      }
    }
  }

  & /deep/ .vjs-custom-skin > .video-js .vjs-big-play-button {
    width: 30px !important;
    height: 30px !important;
    font-size: 20px;
    line-height: 30px !important;
    margin-top: -12px !important;
    margin-left: -16px;
  }
}

.demo-spin-icon-load {
  animation: ani-demo-spin 1s linear infinite;
}

@keyframes ani-demo-spin {
  from {
    transform: rotate(0deg);
  }

  50% {
    transform: rotate(180deg);
  }

  to {
    transform: rotate(360deg);
  }
}

.demo-spin-col {
  height: 100px;
  position: relative;
  border: 1px solid #eee;
}
</style>
